package com.devops.admin.service.impl;

import cn.hutool.core.net.url.UrlBuilder;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.devops.admin.model.IpAddress;
import com.devops.admin.service.IpAddressService;
import com.devops.admin.mapper.IpAddressMapper;
import com.devops.admin.util.Assert;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.nio.charset.Charset;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author Dell
 * @description 针对表【ip_address】的数据库操作Service实现
 * @createDate 2024-07-17 14:13:19
 */
@Service
public class IpAddressServiceImpl extends ServiceImpl<IpAddressMapper, IpAddress>
        implements IpAddressService {

    @Value(value = "${api.url.ip-adress:https://ipqxk.api.bdymkt.com/ip/geo/v1/district/}")
    private String API_URL;

    @Value(value = "${baidu.api.appcode:e4a69b7efc5249d19ae0fa66ec77a47e}")
    private String APP_CODE;

    @Resource
    private ApisixAdminApiServiceImpl apisixAdminApiService;

    @Override
    public IpAddress getIpAddress(String ip) {
        IpAddress ipAddress = getById(ip);
        if (ipAddress != null) {
            return new IpAddress(ip, ipAddress.getIpData());
        }
        // 查询不到，则调用接口获取
        String requestUrl = UrlBuilder.of(API_URL, Charset.defaultCharset())
                .addQuery("ip", ip)
                .addQuery("coordsys", "WGS84")
                .build();

        // 构建请求
        String result = HttpRequest.get(requestUrl)
                .header(Header.CONTENT_TYPE, "application/json;charset=UTF-8")
                .header("X-Bce-Signature", "AppCode/" + APP_CODE)
                .execute()
                .body();

        // 解析结果
        JSONObject jsonObject = new JSONObject(result);
        Assert.isTrue(jsonObject.getStr("code").equals("Success"), "Error processing IP " + ip + ",接口返回结果" + result);
        ipAddress = IpAddress.builder()
                .ip(ip)
                .ipData(jsonObject.getJSONObject("data"))
                .build();
        // 保存
        save(ipAddress);
        return ipAddress;
    }

    @Override
    public List<IpAddress> getIpAddressBatch(List<String> ips) {
        List<CompletableFuture<IpAddress>> futures = new ArrayList<>();
        ips.forEach(ip -> {
            CompletableFuture<IpAddress> future = CompletableFuture.supplyAsync(() -> getIpAddress(ip))
                    .exceptionally(ex -> null);
            futures.add(future);
        });

        return CompletableFuture
                .allOf(futures.toArray(new CompletableFuture[0]))
                .thenApply(v ->
                        futures.stream()
                                .map(CompletableFuture::join)
                                .filter(Objects::nonNull)
                                .collect(Collectors.toList())
                ).join();
    }

    @Override
    public List<String> addBlocklist(List<String> ips) {
        List<String> blockList = apisixAdminApiService.getBlockList();
        blockList.addAll(ips);
        blockList = filterPrivateIPs(blockList);
        return apisixAdminApiService.setBlockList(new HashSet<>(blockList));
    }

    @Override
    public List<String> removeBlocklist(List<String> ips) {
        List<String> blockList = apisixAdminApiService.getBlockList();
        blockList.removeAll(ips);
        return apisixAdminApiService.setBlockList(new HashSet<>(blockList));
    }

    private List<String> filterPrivateIPs(List<String> ipList) {
        // 定义匹配内网 IP 的正则表达式
        String privateIPPattern = "^(192\\.168\\.|10\\.)";
        Pattern pattern = Pattern.compile(privateIPPattern);

        return ipList.stream()
                .filter(ip -> !pattern.matcher(ip).find())
                .collect(Collectors.toList());
    }
}




